
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/services.dart';

class SunmiPrinter {
  static const MethodChannel _channel = MethodChannel('sunmi_printer');

  static Future<void> printerSelfChecking() async {
    await _channel.invokeMethod('printerSelfChecking');
  }

  static Future<void> sendRawData(data) async {
    await _channel.invokeMethod('sendRawData', {
      'data': data
    });
  }

  static Future<void> cutPaper() async {
    await _channel.invokeMethod('cutPaper');
  }

  static Future<void> printerInit() async {
    await _channel.invokeMethod('printerInit');
  }

  static Future<void> lineWrap(n) async {
    await _channel.invokeMethod('lineWrap', {
      'n': n
    });
  }

  static Future<String> getPrinterSerialNo() async {
    return await _channel.invokeMethod('getPrinterSerialNo');
  }

  static Future<String> getPrinterModal() async {
    return await _channel.invokeMethod('getPrinterModal');
  }

  static Future<String> getPrinterVersion() async {
    return await _channel.invokeMethod('getPrinterVersion');
  }

  static Future<String> getPrinterPaper() async {
    return await _channel.invokeMethod('getPrinterPaper');
  }

  static Future<void> setAlignment(int align) async {
    await _channel.invokeMethod('setAlignment', {
      'align': align
    });
  }

  static Future<void> setFontSize(num fontsize) async {
    await _channel.invokeMethod('setFontSize', {
      'fontsize': fontsize
    });
  }

  static Future<void> setPrinterStyle(int key,int value) async {
    await _channel.invokeMethod('setPrinterStyle', {
      'key': key,
      'value': value
    });
  }

  static Future<void> printText(String text) async {
    await _channel.invokeMethod('printText', {
      'text': text
    });
  }

  static Future<void> printTextWithFont({
    required String text,
    required String typeface,
    required num fontsize}) async {
    await _channel.invokeMethod('printTextWithFont', {
      'text': text,
      'typeface': typeface,
      'fontsize': fontsize,
    });
  }

  static Future<void> printOriginalText(String text) async {
    await _channel.invokeMethod('printOriginalText', {
      'text': text
    });
  }

  static Future<void> printColumnsText({
    required List<String> colsTextArr,
    required List<int> colsWidthArr,
    required List<int> colsAlign}) async {
    await _channel.invokeMethod('printColumnsText', {
      'colsTextArr': colsTextArr,
      'colsWidthArr': colsWidthArr,
      'colsAlign': colsAlign,
    });
  }

  static Future<void> printColumnsString({
    required List<String> colsTextArr,
    required List<int> colsWidthArr,
    required List<int> colsAlign}) async {
    await _channel.invokeMethod('printColumnsString', {
      'colsTextArr': colsTextArr,
      'colsWidthArr': colsWidthArr,
      'colsAlign': colsAlign,
    });
  }

  static Future<void> printBarCode({
    required String data,
    int symbology = 8,
    required int height,
    required int width,
    int textposition = 0}) async {
    await _channel.invokeMethod('printBarCode', {
      'data': data,
      'symbology': symbology,
      'height': height,
      'width': width,
      'textposition': textposition,
    });
  }

  static Future<void> printQRCode({
    required String data,
    required int modulesize,
    int errorlevel = 2}) async {
    await _channel.invokeMethod('printQRCode', {
      'data': data,
      'modulesize': modulesize,
      'errorlevel': errorlevel,
    });
  }

  static Future<void> printQrCodeImage({
    required String data,
    int format = 9,
    required int width,
    required int height}) async {
    await _channel.invokeMethod('printQRCodeImage', {
      'data': data,
      'format': format,
      'width': width,
      'height': height
    });
  }

  static Future<void> printBitmap(Uint8List bytes) async {
    await _channel.invokeMethod('printBitmap', {
      'bytes': bytes,
    });
  }
  
  static Future<int?> updatePrinterState() async {
    return await _channel.invokeMethod('updatePrinterState');
  }

  static Future<void> labelLocate() async {
    await _channel.invokeMethod('labelLocate');
  }

  static Future<void> labelOutput() async {
    await _channel.invokeMethod('labelOutput');
  }

}
